﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;

namespace TemplateLibraryConnector.Utility
{
    public class TemplateLibraryUtility
    {



        /// <summary>
        /// Get site url
        /// </summary>
        /// <param name="fullUrl">Assume the following url structure http://sp2010/sites/devramblings/_layouts/listedit.aspx?List=%7B29B3C...</param>
        /// <returns></returns>
        internal static string GetSiteUrlFromListEdit(string fullUrl)
        {
            var index = fullUrl.IndexOf("?", System.StringComparison.Ordinal);
            fullUrl = index >= 0 ? fullUrl.Substring(0, index) : fullUrl;

            var cleanUrl = HttpUtility.UrlDecode(fullUrl);
            if (cleanUrl == null)
                return null;

            var urlWithOutForms = cleanUrl.Replace("_layouts/15/listedit.aspx", "");

            if (!urlWithOutForms.EndsWith("/"))
                urlWithOutForms = urlWithOutForms + ('/');

            return urlWithOutForms;
        }

        


        internal static SPDocumentLibrary GetTemplateDocumentLibrary(string webId, string templateListId, string templateHubUrl)
        {
            if (String.IsNullOrEmpty(webId) || String.IsNullOrEmpty(templateListId))
                return null;

            SPWeb web = null;
            try
            {
                web = OpenWebById(webId, templateHubUrl);
                if (web == null)
                    return null;

                var listId = new Guid(templateListId);

                // If the user does not have access to the library, we must be careful not to use GetList()
                web.Lists.ListsForCurrentUser = true;
                var lists = web.Lists.Cast<SPList>().ToList();
                if ((lists.Where(t => t.ID == listId)).Count() == 0)
                    return null;

                // The user has access, so we can safely use web.Lists.GetList() or web.Lists[]
                var library = (SPDocumentLibrary) web.Lists.GetList(listId, false);

                return library;
            }
            catch (Exception)
            {
                /* Error fetching list, or invalid list id: in either case return null */
            }
            finally
            {
                if (web != null)
                    web.Dispose();
            }
            return null;
        }

        /// <summary>
        /// Open the webpart's source web, based on the properties.
        /// 'Open' implies that ownership of the SPWeb object is passed on
        /// to the caller. Clearly put: If you get a SPWeb from this function,
        /// *you* should Dispose() it.
        /// </summary>
        /// <returns></returns>
        internal static SPWeb OpenWebById(string webId, string templateHubUrl)
        {
            using (var site = new SPSite(templateHubUrl))
            {
                var web = site.OpenWeb(new Guid(webId));
                return web;
            }
        }

        internal static IEnumerable<SPFolder> GetTemplateLibraryRootFolders(TemplateLibrarySettings settings, string defaultHubAddress)
        {
            var webIds = settings.WebIds.Split(',');
            var templateListIds = settings.TemplateListIds.Split(',');

            var templateLibraries = new SPDocumentLibrary[webIds.Length];
            var rootFolders = new SPFolder[webIds.Length];

            for (var i = 0; i < webIds.Length; i++)
            {
                templateLibraries[i] = GetTemplateDocumentLibrary(webIds[i], templateListIds[i], settings.GetTemplateHubAddress(defaultHubAddress));
                if (templateLibraries[i] != null && templateLibraries[i].RootFolder != null)
                    rootFolders[i] = templateLibraries[i].RootFolder;
            }

            return rootFolders.Where(t => t != null).ToList();
        }

        internal static IEnumerable<string> GetSelectedTemplateLibraries(TemplateLibrarySettings settings)
        {
            var selectedTemplateLibraries = new string[] {};
            if (settings.WebIds != null && settings.TemplateListIds != null)
            {
                var templateListIds = settings.TemplateListIds.Split(',');
                var webIds = settings.WebIds.Split(',');

                selectedTemplateLibraries = new string[webIds.Length];
                for (var i = 0; i < webIds.Length; i++)
                {
                    selectedTemplateLibraries[i] = String.Format("{0}|{1}", webIds[i], templateListIds[i]);
                }
            }
            return selectedTemplateLibraries;
        }

        internal static void AddRelevantDocumentLibraries(SPWeb web, TreeNode webNode, IEnumerable<string> nodes)
        {
            foreach (var listNode in from SPList list in web.Lists where IsRelevant(list) 
                        select new TreeNode(list.Title, String.Format("{0}|{1}", web.ID, list.ID), "/_layouts/images/list.gif") {SelectAction = TreeNodeSelectAction.None})
            {
                foreach (var node in nodes.Where(node => listNode.Value == node))
                    listNode.Checked = true;

                webNode.ChildNodes.Add(listNode);
            }
        }

        internal static bool IsRelevant(SPList list)
        {
            var isSPDocumentLibrary = list is SPDocumentLibrary;
            var isCustomMade = list.Title != "Style Library" &&
                                list.Title != "Form Templates" &&
                                list.Title != "Customized Reports";
            var isVisible = !list.Hidden;

            return isSPDocumentLibrary && isCustomMade && isVisible;
        }
    }
}